/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.inspur.edp.web.formmetadata.replication;

import com.inspur.edp.lcm.metadata.api.IMetadataContent;
import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;
import com.inspur.edp.lcm.metadata.api.entity.MetadataDto;
import com.inspur.edp.web.common.customexception.WebCustomException;
import com.inspur.edp.web.common.io.FileUtility;
import com.inspur.edp.web.common.utility.StringUtility;
import com.inspur.edp.web.formmetadata.constant.I18nExceptionConstant;
import com.inspur.edp.web.formmetadata.replication.adjust.CloneAdjustStrategyFactory;

import java.util.ArrayList;

/**
 * description:
 *
 * @author Noah Guo
 * @date 2021/02/26
 */
class MetadataCloneManager {
    /**
     * 元数据克隆
     *
     * @param metadataReplicationContext
     * @return
     */
    public static GspMetadata cloneMetadata(MetadataReplicationContext metadataReplicationContext) {
        GspMetadata sourceMetadata = metadataReplicationContext.getSourceMetadata();
        MetadataDto metadataDto = metadataReplicationContext.getTargetMetadataDescription();

        // 复制前检测（仅支持同一个BO内复制--需保证）
        // 现有元数据描述和元数据内容存在两个层次的数据一致性问题：元数据Code和元数据命名空间。当前，仅处理元数据Code上的数据不一致问题，元数据命令空间的数据不一致后续处理。
        if ((metadataDto.getNameSpace() != null && !metadataDto.getNameSpace().equals(sourceMetadata.getHeader().getNameSpace())) ||
                (metadataDto.getBizobjectID() != null && !metadataDto.getBizobjectID().equals(sourceMetadata.getHeader().getBizobjectID()))) {
            throw new WebCustomException(I18nExceptionConstant.WEB_FORM_METADATA_ERROR_0012);
        }


        // 检测 MetadataDto
        if (StringUtility.isNotNullOrEmpty(metadataDto.getCode()) && StringUtility.isNullOrEmpty(metadataDto.getFileName())) {

            if (StringUtility.isNullOrEmpty(metadataReplicationContext.getTargetFileName())) {
                String fileSuffix = FileUtility.getFileExtension(sourceMetadata.getHeader().getFileName());
                metadataDto.setFileName(metadataDto.getCode() + fileSuffix);
            } else {
                metadataDto.setFileName(metadataReplicationContext.getTargetFileName());
            }

        }
        GspMetadata replicateMetadata = new GspMetadata();
        // 复制MetadataHeader
        replicateMetadata.setHeader(MetadataHeaderCloneManager.cloneMetadataHeader(sourceMetadata, metadataDto));

        // 依赖关系置空
        replicateMetadata.setRefs(new ArrayList<>());

        // 复制元数据内容实体
        replicateMetadata.setContent(MetadataContentCloneManager.deepClone(sourceMetadata, metadataDto));

        // 更新元数据内容（保证元数据描述和元数据内容的数据一致性）
        IMetadataContent replicateMetadataContent = replicateMetadata.getContent();

        // 执行元数据参数调整
        CloneAdjustStrategyFactory.build(replicateMetadataContent).adjust(replicateMetadata, replicateMetadataContent, metadataReplicationContext);


        // 复制元数据上其他属性
        StringUtility.executeIfPresentOrOther(metadataDto.getRelativePath(), StringUtility::isNotNullOrEmpty, replicateMetadata::setRelativePath,
                (param) -> replicateMetadata.setRelativePath(sourceMetadata.getRelativePath()));

        replicateMetadata.setExtended(sourceMetadata.isExtended());
        if (metadataDto.isExtendable()) {
            replicateMetadata.setExtended(metadataDto.isExtendable());
        }

        replicateMetadata.setExtendProperty(sourceMetadata.getExtendProperty());
        replicateMetadata.setPreviousVersion(null);
        replicateMetadata.setVersion(null);

        return replicateMetadata;
    }


}
